package com.tcheung;

import com.tcheung.entity.Document;
import com.tcheung.entity.TFIDFEntity;
import com.tcheung.service.IndexService;
import com.tcheung.service.QueryService;

import java.util.*;

/**
 * 向量空间模型
 *
 * @author: zhangteng
 * @time: 2014/12/28 17:25
 */
public class VSM {

    public static void cosSim(List<Document> documentList, int queryNum) {
        IndexService indexService = IndexService.getInstance();
        QueryService queryService = QueryService.getInstance();
        Map<String, TFIDFEntity> queryIndexes = queryService.getQueryIndexesByQueryNum(queryNum);
       // System.out.println(queryIndexes.size());
        for (Document document : documentList) {
            Map<String, TFIDFEntity> docIndexes = indexService.getDocIndexesByDocNum(document.getDocNum());
            // 分子
            Double element = 0.0;
            Double denominator = 0.0, denominator1 = 0.0, denominator2 = 0.0;
            // 计算分子
            for (Map.Entry<String, TFIDFEntity> entry : queryIndexes.entrySet()) {
                TFIDFEntity tfidfEntity = entry.getValue();
                if (docIndexes.containsKey(entry.getKey())) {
                    element += tfidfEntity.getTfidf() * docIndexes.get(tfidfEntity.getKeyWord()).getTfidf();
                    // System.out.println(tfidfEntity.getKeyWord() + "   " + tfidfEntity.getTfidf());
                }
                denominator1 += Math.pow(tfidfEntity.getTfidf(), 2.0);
            }
            for (TFIDFEntity tfidfEntity : docIndexes.values()) {
                denominator2 += Math.pow(tfidfEntity.getTfidf(), 2.0);
            }
            denominator = Math.sqrt(denominator1) * Math.sqrt(denominator2);

            Double similarity = 0.0;
            if (denominator.compareTo(0.0) != 0) {
                similarity = element / denominator;
            }
            document.setSimilarity(similarity);
        }
        // 按照相似度排序
        Collections.sort(documentList, new Comparator<Document>() {
            @Override
            public int compare(Document o1, Document o2) {
                return o2.getSimilarity().compareTo(o1.getSimilarity());
            }
        });
        // 将结果添加到结果记录中
        List<Integer> answerList = new ArrayList<Integer>();
        for (Document document : documentList) {
            answerList.add(document.getDocNum());
        }
        queryService.addAnswer(queryNum, answerList);
    }
}
